package com.tcm.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.tcm.entity.Clazz;
import com.tcm.entity.Code;
import com.tcm.entity.Organization;
import com.tcm.entity.dto.CodeUpdateDto;
import com.tcm.entity.vo.ClazzSelectResult;
import com.tcm.entity.vo.GradeSelectResult;
import com.tcm.entity.vo.OrgSelectResult;
import com.tcm.service.ClazzService;
import com.tcm.service.CodeService;
import com.tcm.service.OptionsService;
import com.tcm.service.OrganizationService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author Guqier
 * @version 1.0
 * @date 2023/7/8 17:27
 */
@Service
public class OptionsServiceImpl implements OptionsService {

    /**
     * 学院类型表示
     */
    private static final int COLLEGE_TYPE_CODE = 0;

    /**
     * 专业类型表示
     */
    private static final int MAJOR_TYPE_CODE = 1;

    /**
     * 年级码表类型表示
     */
    private static final String GRADE_TYPE = "grade";

    /**
     * 图片类型码表类型
     */
    private static final String IMAGE_TYPE = "imageType";

    /**
     * 题目难度码表类型
     */
    private static final String DIFF_TYPE = "difficulty";

    /**
     * 病症类别码表类型
     */
    private static final String CATEGORY_TYPE = "category";

    /**
     * 社会化项目类型
     */
    public static final String PROJECT_TYPE = "projectType";

    /**
     * 考试难度
     */
    public static final String TEST_DIFF_TYPE = "testDiff";

    @Autowired
    private OrganizationService orgService;

    @Autowired
    private CodeService codeService;

    @Autowired
    private ClazzService clazzService;

    /**
     * 获取学院列表，用于前端Select组件展示
     * @return 学院列表
     */
    @Override
    public List<OrgSelectResult> getCollegeList(){
        // 从组织机构中查询学院
        LambdaQueryWrapper<Organization> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Organization::getType, COLLEGE_TYPE_CODE);
        queryWrapper.orderByAsc(Organization::getSequence);
        List<Organization> list = orgService.list(queryWrapper);

        // 将查询结果封装到响应集
        List<OrgSelectResult> res = new LinkedList<>();
        for (Organization organization : list) {
            OrgSelectResult orgSelectResult = new OrgSelectResult();
            BeanUtils.copyProperties(organization, orgSelectResult);

            res.add(orgSelectResult);
        }
        return res;
    }

    /**
     * 获取指定学院下的专业选项列表
     * @param collegeId 学院ID
     * @return 选项列表
     */
    @Override
    public List<OrgSelectResult> getMajorList(Long collegeId){
        // 从组织机构中查询指定学院下的专业
        LambdaQueryWrapper<Organization> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Organization::getType, MAJOR_TYPE_CODE).eq(Organization::getParentId, collegeId);
        queryWrapper.orderByAsc(Organization::getSequence);
        List<Organization> list = orgService.list(queryWrapper);

        // 将查询结果封装到响应集
        List<OrgSelectResult> res = new LinkedList<>();
        for (Organization organization : list) {
            OrgSelectResult orgSelectResult = new OrgSelectResult();
            BeanUtils.copyProperties(organization, orgSelectResult);

            res.add(orgSelectResult);
        }
        return res;
    }

    /**
     * 获取年级选项列表
     * @return 年级列表
     */
    @Override
    public List<GradeSelectResult> getGradeList(){
        LambdaQueryWrapper<Code> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Code::getType, GRADE_TYPE);
        queryWrapper.orderByAsc(Code::getSequence);

        List<Code> list = codeService.list(queryWrapper);
        List<GradeSelectResult> res = new ArrayList<>();
        for (Code code : list) {
            GradeSelectResult gradeSelectResult = new GradeSelectResult();
            BeanUtils.copyProperties(code, gradeSelectResult);
            // 计算年级号
            String str = code.getCode();
            String substring = str.substring(2);
            gradeSelectResult.setGrade(Integer.parseInt(substring));

            res.add(gradeSelectResult);
        }
        return res;
    }

    /**
     * 获取指定班级列表
     * @param majorId 专业ID
     * @param gradeId 年级ID
     * @return 班级列表
     */
    @Override
    public List<ClazzSelectResult> getClazzSelectList(Long majorId, Long gradeId){
        LambdaQueryWrapper<Clazz> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(majorId != null, Clazz::getMajorId, majorId).eq(gradeId != null, Clazz::getGradeId, gradeId);
        queryWrapper.orderByDesc(Clazz::getUpdateTime);
        List<Clazz> list = clazzService.list(queryWrapper);
        // 封装响数据
        List<ClazzSelectResult> res = new ArrayList<>();
        for (Clazz clazz : list) {
            ClazzSelectResult clazzSelectResult = new ClazzSelectResult();
            BeanUtils.copyProperties(clazz, clazzSelectResult);
            res.add(clazzSelectResult);
        }
        return res;
    }

    /**
     * 获取图片类型列表
     * @return 图片类型列表
     */
    @Override
    public List<CodeUpdateDto> getImageTypeList(){
        return getCodeUpdateDtos(IMAGE_TYPE);
    }

    /**
     * 获取题目难度列表
     * @return 题目难度列表
     */
    @Override
    public List<CodeUpdateDto> getItemDifficultyList(){
        return getCodeUpdateDtos(DIFF_TYPE);
    }

    /**
     * 获取社会化项目类型列表
     * @return 社会化项目类型列表
     */
    @Override
    public List<CodeUpdateDto> getSocialProjectType(){
        return getCodeUpdateDtos(PROJECT_TYPE);
    }

    /**
     * 获取码表指定类型列表
     * @param codeType 码表类型
     * @return 码表列表
     */
    private List<CodeUpdateDto> getCodeUpdateDtos(String codeType) {
        LambdaQueryWrapper<Code> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Code::getType, codeType);
        List<Code> list = codeService.list(queryWrapper);
        return list.stream().map(c -> {
            CodeUpdateDto codeUpdateDto = new CodeUpdateDto();
            BeanUtils.copyProperties(c, codeUpdateDto);
            return codeUpdateDto;
        }).collect(Collectors.toList());
    }

    /**
     * 获取主观题病症类别列表
     * @return 病症类别列表
     */
    @Override
    public List<CodeUpdateDto> getCategoryList(){
        return getCodeUpdateDtos(CATEGORY_TYPE);
    }

    /**
     * 获取考试难度列表
     * @return 考试难度列表
     */
    @Override
    public List<CodeUpdateDto> getTestDiffList(){
        return getCodeUpdateDtos(TEST_DIFF_TYPE);
    }

}
